package com.senyint.imsdk.http;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;

/**
 * 简单的http工具类<br>
 * 包括get,post请求，以及上传，下载功能
 * @author hui
 *
 */
public class SimpleHttp implements ISimpleHttpService{
	private static final String TAG = SimpleHttp.class.getSimpleName();
	
	private final static int CONNECT_TIME_OUT = 10000;
	private final static int READ_TIME_OUT = 10000;
	
	/**
	 * 发送GET请求
	 * 
	 * @param url
	 * @param params
	 * @return
	 * @throws IOException
	 * @throws Exception
	 */
	public String get(String url,Map<String,String> params,HttpCallback callback) {
		HttpURLConnection connection = null ;
		StringBuffer tempUrl = new StringBuffer();
		boolean where = false ;
		if(url.indexOf("?") != -1){
			where = true ;
		}
		try {
			if (params != null && !params.isEmpty()) {
				for(String key:params.keySet()){
					tempUrl.append(key).append("=").append(URLEncoder.encode(params.get(key),"UTF-8")).append("&");
				}
				tempUrl.deleteCharAt(tempUrl.length() - 1);
			}
			url = where?url+tempUrl.toString():url+"?"+tempUrl.toString() ;
		
			connection = getHttpURLConnection(url, HttpHeader.METHOD_GET);
			if (connection.getResponseCode() == 200) {
				InputStream inStream = connection.getInputStream();
				byte[] number = read(inStream);
				if(callback != null){
					callback.onSuccess(number);
				}
				return new String(number);
			}else{
				if(callback != null){
					callback.onFailure("{\"code\":\""+connection.getResponseCode()+"\"");
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			if(callback != null){
				callback.onFailure("{\"error\":\""+e.getMessage()+"\"");
			}
		}
		
		return null;
	}
	
	public String post(String url, Map<String, String> map, HttpCallback callback) {
		HttpURLConnection connection = null;
		try {
			StringBuilder data = new StringBuilder();
			// 数据拼接 key=value&key=value
			if (map != null && !map.isEmpty()) {
				for (Map.Entry<String, String> entry : map.entrySet()) {
					data.append(entry.getKey()).append("=");
					data.append(URLEncoder.encode(entry.getValue(), HttpHeader.ENCODING_UTF8));
					data.append("&");
				}
				data.deleteCharAt(data.length() - 1);
			}

			byte[] entity = data.toString().getBytes();// 生成实体数据
			
			connection = getHttpURLConnection(url, HttpHeader.METHOD_POST);

			connection.setDoOutput(true);// 允许对外输出数据

			connection.setRequestProperty("Content-Length",String.valueOf(entity.length));

			OutputStream outStream = connection.getOutputStream();
			outStream.write(entity);
			if (connection.getResponseCode() == 200) {// 成功返回处理数据
				InputStream inStream = connection.getInputStream();
				byte[] number = read(inStream);
				if(callback != null){
					callback.onSuccess(number);
				}
				return new String(number);
			}else{
				if(callback != null){
					callback.onFailure("{\"code\":\""+connection.getResponseCode()+"\"");
				}
			}
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			if(callback != null){
				callback.onFailure("{\"error\":\""+e.getMessage()+"\"");
			}
		}

		return null;
	}
	
	/**
	 * 发送文件post请求
	 * 
	 * @param path
	 * @param params
	 * @param string
	 * @return
	 * @throws IOException
	 */
	public byte[] upload(String uploadUrl, Map<String, String> params,Map<String, File> files,HttpCallback callback) {
		String BOUNDARY = "----WebKitFormBoundaryDwvXSRMl0TBsL6kW"; // 定义数据分隔线

		URL url = null ;
		try {
			url = new URL(uploadUrl);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			// 发送POST请求必须设置如下两行
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setUseCaches(false);
			connection.setRequestMethod(HttpHeader.METHOD_POST);
			connection.setRequestProperty("Accept", "*/*");
			connection.setRequestProperty("connection", "Keep-Alive");
			connection.setRequestProperty("user-agent", "Android/Cinyi");
			connection.setRequestProperty("Charsert", "UTF-8");
			connection.setRequestProperty("Accept-Encoding", "gzip,deflate");
			connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

			OutputStream out = new DataOutputStream(connection.getOutputStream());
			byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();// 定义最后数据分隔线

			// 文件
			if (files != null && !files.isEmpty()) {
				for (Map.Entry<String, File> entry : files.entrySet()) {
					File file = entry.getValue();
					String fileName = entry.getKey();

					StringBuilder sb = new StringBuilder();
					sb.append("--");
					sb.append(BOUNDARY);
					sb.append("\r\n");
					sb.append("Content-Disposition: form-data;name=\"" + fileName
							+ "\";filename=\"" + file.getName() + "\"\r\n");
					sb.append("Content-Type: image/jpg\r\n\r\n");
					byte[] data = sb.toString().getBytes();
					out.write(data);

					DataInputStream in = new DataInputStream(new FileInputStream(
							file));
					int bytes = 0;
					byte[] bufferOut = new byte[1024];
					while ((bytes = in.read(bufferOut)) != -1) {
						out.write(bufferOut, 0, bytes);
					}
					out.write("\r\n".getBytes()); // 多个文件时，二个文件之间加入这个
					in.close();
				}
			}
			// 数据参数
			if (params != null && !params.isEmpty()) {

				for (Map.Entry<String, String> entry : params.entrySet()) {
					StringBuilder sb = new StringBuilder();
					sb.append("--");
					sb.append(BOUNDARY);
					sb.append("\r\n");
					sb.append("Content-Disposition: form-data; name=\""
							+ entry.getKey() + "\"");
					sb.append("\r\n");
					sb.append("\r\n");
					sb.append(entry.getValue());
					sb.append("\r\n");
					byte[] data = sb.toString().getBytes();
					out.write(data);
				}
			}
			out.write(end_data);
			out.flush();
			out.close();

			// 定义BufferedReader输入流来读取URL的响应
			// BufferedReader reader = new BufferedReader(new InputStreamReader(
			// connection.getInputStream()));
			// String line = null;
			// while ((line = reader.readLine()) != null) {
			// System.out.println(line);
			// }

			if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
				InputStream inStream = connection.getInputStream();
				byte[] response = read(inStream);
				if(callback != null){
					callback.onSuccess(response);
				}
			}else{
				if(callback != null){
					callback.onFailure("{\"code\":\""+connection.getResponseCode()+"\"");
				}
			}

		} catch (MalformedURLException e) {
			e.printStackTrace();
			if(callback != null){
				callback.onFailure("{\"error\":\""+e.getMessage()+"\"");
			}
		} catch (IOException e) {
			e.printStackTrace();
			if(callback != null){
				callback.onFailure("{\"error\":\""+e.getMessage()+"\"");
			}
		}
		
		return null;
	}

	public void download(String uri ,String destFilePath, HttpCallback callback){
		InputStream is = null ;
		BufferedInputStream bis = null ;
		byte[] buffer = null ;
		RandomAccessFile destFile = null ;
		HttpURLConnection conn = null ;
		try{
			if(destFilePath == null){
				throw new FileNotFoundException(" the dest file must be required!" );
			}
			URL url = new URL(uri);
            conn  = (HttpURLConnection)url.openConnection();
//            conn.setDoInput(true);
            conn.setRequestMethod(HttpHeader.METHOD_GET);
//            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.connect(); 
            
            File file = new File(destFilePath);
        	
        	int respCode = conn.getResponseCode();
        	
			if (respCode == 200) {
				is = conn.getInputStream();
				
				FileOutputStream fos = new FileOutputStream(file);
				buffer = new byte[1024];
				int len = 0;
				while ((len = is.read(buffer)) != -1) {
					fos.write(buffer, 0, len);
				}
				is.close();
				fos.close(); 
				
				if(callback!=null){
					callback.onSuccess(file.getAbsolutePath().getBytes());
				}
			}else{
				if(callback!=null){
					callback.onFailure("{\"code\":\""+respCode+"\"");
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
			if(callback!=null){
				callback.onFailure("{\"error\":\""+e.getMessage()+"\"");
			}
		}finally{
			buffer = null ;
			try {
				if(bis != null ){
					bis.close();
				}
				if(destFile != null ){
					destFile.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			} 

			if(conn != null ){
				conn.disconnect();
				conn = null ;
			}
			System.gc();
		}
	}

	private HttpURLConnection getHttpURLConnection(String urlstr, String method)
			throws IOException {
		URL url = new URL(urlstr);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setConnectTimeout(CONNECT_TIME_OUT);
		connection.setReadTimeout(READ_TIME_OUT);
		connection.setRequestMethod(method);

		// 头字段
		connection.setRequestProperty("Accept", "*/*");
		connection.setRequestProperty("Accept-Charset", "UTF-8,*;q=0.5");
		connection.setRequestProperty("Accept-Encoding", "gzip,deflate");
		connection.setRequestProperty("Accept-Language", "zh-CN");
		connection.setRequestProperty("User-Agent", "Android WYJ");
		connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");// 头字段

		return connection;

	}
	
	/**
	 * 读取输入流数据 InputStream
	 * 
	 * @param inStream
	 * @return
	 * @throws IOException
	 */
	private byte[] read(InputStream inStream) throws IOException {
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}
		inStream.close();
		return outStream.toByteArray();
	}
	
}


